﻿// --------------------------------------------------------------------------------------------------------------------- 
// <copyright file="T4TemplatePropertyEditor.cs" company="Microsoft.Blueprints.Contrib Team">
//   (C) 2009 Microsoft.Blueprints.Contrib Team
// </copyright>
// <summary>
//   Defines the T4TemplatePropertyEditor type.
// </summary>
// ---------------------------------------------------------------------------------------------------------------------

namespace Microsoft.Blueprints.Contrib.Dialogs
{
    #region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Linq.Dynamic;
    using System.Windows.Forms;

    using Contracts.T4;

    using Microsoft.Blueprints.Contrib.T4;
    using Microsoft.SoftwareFactories.Blueprints;

    #endregion

    /// <summary>
    /// A reusable property editor for T4 Template files.
    /// </summary>
    public partial class T4TemplatePropertyEditor : Form, IT4TemplateProperties
    {
        /// <summary>
        /// The dynamically created type.
        /// </summary>
        private readonly Type dynamicType;

        /// <summary>
        /// Dictionary which contains the properties and data exposed by the T4 Template
        /// </summary>
        private Dictionary<string, T4PropertyData> properties = new Dictionary<string, T4PropertyData>();

        /// <summary>
        /// Initializes a new instance of the <see cref="T4TemplatePropertyEditor"/> class.
        /// </summary>
        public T4TemplatePropertyEditor()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="T4TemplatePropertyEditor"/> class.
        /// </summary>
        /// <param name="template">
        /// The context.
        /// </param>
        public T4TemplatePropertyEditor(T4Template template) : this()
        {
            this.Template = template;
            this.Properties = template.Properties;

            List<DynamicProperty> dynamicProperties = new List<DynamicProperty>();

            foreach (KeyValuePair<string, T4PropertyData> pair in template.Properties)
            {
                dynamicProperties.Add(new DynamicProperty(pair.Key, pair.Value.Type));
            }

            this.dynamicType = DynamicExpression.CreateClass(dynamicProperties);
            object templateProperties = Activator.CreateInstance(this.dynamicType);

            this.propertyGrid.SelectedObject = templateProperties;
        }

        /// <summary>
        /// Gets or sets the Properties.
        /// </summary>
        /// <value>
        /// The properties.
        /// </value>
        public Dictionary<string, T4PropertyData> Properties
        {
            get
            {
                return this.properties;
            }

            set
            {
                this.properties = value;
            }
        }

        /// <summary>
        /// Gets or sets Template.
        /// </summary>
        /// <value>
        /// The template.
        /// </value>
        public T4Template Template
        {
            get;
            set;
        }

        /// <summary>
        /// The event handler for the Cancel Button
        /// </summary>
        /// <param name="sender">
        /// The sender of the event.
        /// </param>
        /// <param name="e">
        /// The event data.
        /// </param>
        private void OnCancelButtonClicked(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// The event handler for the OK Button
        /// </summary>
        /// <param name="sender">
        /// The sender of the event.
        /// </param>
        /// <param name="e">
        /// The event data.
        /// </param>
        private void OnOkButtonClicked(object sender, EventArgs e)
        {
            Dictionary<string, T4PropertyData> updatedProperties = new Dictionary<string, T4PropertyData>();

            foreach (KeyValuePair<string, T4PropertyData> pair in this.properties)
            {
                string value = (string)this.dynamicType.GetProperty(pair.Key).GetValue(this.propertyGrid.SelectedObject, null);

                updatedProperties.Add(pair.Key, new T4PropertyData(value, pair.Value.Type));
            }

            this.Properties = updatedProperties;

            this.Close();
        }
    }
}